package com.slz3.business.frame.api.alipay;

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradeFastpayRefundQueryModel;
import com.alipay.api.domain.AlipayTradeQueryModel;
import com.alipay.api.domain.AlipayTradeRefundModel;
import com.alipay.api.request.AlipayTradeFastpayRefundQueryRequest;
import com.alipay.api.request.AlipayTradeQueryRequest;
import com.alipay.api.request.AlipayTradeRefundRequest;
import com.alipay.api.response.AlipayTradeFastpayRefundQueryResponse;
import com.alipay.api.response.AlipayTradeQueryResponse;
import com.alipay.api.response.AlipayTradeRefundResponse;
import lombok.extern.slf4j.Slf4j;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @FileName: AliPayUtil
 * @Description: 支付宝退款及查询工具类
 */

@Slf4j
public class AliPayUtil {

    private static final String ALIPAY_URL="https://openapi.alipay.com/gateway.do";

    private static final String PARTNER ="2018071460726101";

    private static final String PRIVATE_KEY="MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDBD+DHHrw3GyqCsJ7h5G7obbNXMNjMsW0tVPuSdXTQucN4YCSL3E3Fh+UV6hrcSKoGfySVWhY9yyHjY5P0mooaDIbVwYEqj/EMfIxBP+IE14kAvD2sbT0A6PU+P9RyQZyDK3U/2WEppU52r23IxgsKTwaaGrrBUOOEZ3PTS74FBqb9CDkY3sHnLbGYFqpwVuqmcRoduhBbho6RcjQJnlvffQ5jpiP6Le1QN83mdxXInyerJiFKDCWd4E/Tcn55rgr5n/AA3laEXhjfe7GlAG825eXOSOqjfhaug4+PGjZin87H/VSBqST538n4LNyAbJpS3wTYlIoPzkOvdhbNyV7TAgMBAAECggEBAIN2Hmc4RI15kB7hya6j7+mRGXebqWToxCEEJzH5jQu8EqBbR0d9Qe/ps1KS0KuDR1OZK/4PE+oL8g12dv8uZC+MrBvN4fhrf4YzIQYlS/BkG8RGafCJieqetrAmorESgFLJOtO5X/INwDoNBsKaKFZirWouHVEZlXNJRpNwlfmw+JmxVyshXfKdVdBZGf4ZhvTX6DzbRnF51RHLT0wd1qEfkKpkYg0eD4zsxp3mDTmSXUcj/myOPARHRZeYJR1y+gAAxwIaLTeZ4FvMNE7BrwKMK35eAM1sh5tOEFFzg5K6/tyxrPMvXGBwU5vmMPxwXdHhwJ/YBhuhhDiml2n2P4ECgYEA7G02sCmUT3oTGt3C3+SKbHxRK4WJpgWgb/OqI5IHSnUSlU2I3JmrY8rIXzyIMGztS+BUyTRYzugEH4Z/+tcGCXkJB/RZ0Tg5oBUy89bnXhk6ik9gXRM9nDiFZfn2BU8DIm7jVg62UkTSKBQO9HXbQpvBnRdLLphhjzcSXz86/+ECgYEA0QuaOr4dKAXlSyrobHWirb3TK6leAIyISghmLkcTP7oqHxR0yxdnCEJfeczjUxbhmth/dnxEPbgOOUdxFOwGxAAtfzmuOrwdLNcEHrl+AkHBz2H8zs2RcDdixcH01hIApBbUY3QbBBa4UWIATPeAzAFq1aWh8Q4gWiQu/HMpBTMCgYEAt10MqRvWVr2Ky69qUFLjuLfCDEsJMqXyhGEqd2PuG6UowHrdxpm3/zFqrdI4nbYdZFeb6mCa7/2qFPkvkM/rcrVYd77fWhCNQMawOcVWs/hFGrftOMKPafW8IBb4460f9TijQD8w0CVoCIVmA9rULpi2VKuYN48fOv+vVAeqLoECgYBjBnD/5LEhFXHh4qiJQExYqzROWYO7FNc24rWstGSM6p4rbOBKmIJpKi/aHdGNuagTVv1CXmlhJ0AtqAcMVyZ5UHA89VDwZ84WQKCmAU6MuSObHprISB7eHo5+iXt2sL52/I2NsyFdFXooqxjjXNc5TG6UWErXSs7OhJdxZQgIewKBgQDR+ccyjzua0sYQ7ftwocNedAqijiSPBBt0yxBzn9GhHyeORoMNrZNdqku27voQkAEojwM4lx2ebcuzaKo79ujX4pwGQboX2aNcZMlz1fJ/gTUDEmuN1qFqFsusjnOIVASWYH1gKJhX1K1qhKNiArHcPQP7wYVDmIhRoDwFsYZwpw==";

    private static final String PUBLIC_KEY ="MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnpRS6k148Tqop4M9TQTtYzjaNJMVwAZuapcj6kQzQVUd3fA5ditHzNH8qAD/MdgdjI1zbw29fj1Q5tT7pdginCC8WCy+52pZQo2D3AwjM6abkC/XcGRlPvySpaog8INMWTX8fhT572R21H9gF9aHpAtYZGSz1rvCp/dTkxcaf/lnKnl6ffcAlBGDl1OiY1fYW4UIOA/ocMJj24+0MTsvDMnf93nl8rRNrq1cVE+z7NoJi4qCL99hH17pczaHG20kj95EUJEMuY3KchOtSCY87k88cCivMENVqXJEGTT1ttZtvP/eNZqWrH5yr+wB9vbMEtA0K1tQUdB9UK7tlj2wMQIDAQAB";
    private static final String ALIPAY_FOMATE="json";

    private static final String CHARSET ="utf-8";
    private static final AlipayClient alipayClient = new DefaultAlipayClient(ALIPAY_URL,PARTNER,PRIVATE_KEY,ALIPAY_FOMATE,CHARSET,PUBLIC_KEY,"RSA2");


    /**
     * @Description：统一收单线下交易查询
     * @param orderno 商家交易编号
     */
    public static Map<String,String> orderPayQuery(String orderno) {
        log.info("orderPayQuery");
        // 返回提交支付宝订单交易查询信息
        Map<String, String> restmap = new HashMap<String, String>();
        // 统一收单线下交易查询
        AlipayTradeQueryRequest alipayRequest = new AlipayTradeQueryRequest();
        // 只需要传入业务参数
        AlipayTradeQueryModel model = new AlipayTradeQueryModel();
        // 商户订单号
        model.setOutTradeNo(orderno);
        alipayRequest.setBizModel(model);
        try {
            AlipayTradeQueryResponse alipayResponse =alipayClient.execute(alipayRequest);
            // 订单查询成功
            if (alipayResponse.isSuccess()) {
                // 调用成功，则处理业务逻辑
                if ("10000".equals(alipayResponse.getCode())) {
                    restmap.put("order_no", alipayResponse.getOutTradeNo());
                    restmap.put("trade_no", alipayResponse.getTradeNo());
                    restmap.put("buyer_logon_id", alipayResponse.getBuyerLogonId());
                    //交易状态：WAIT_BUYER_PAY（交易创建，等待买家付款）、TRADE_CLOSED（未付款交易超时关闭，或支付完成后全额退款）、TRADE_SUCCESS（交易支付成功）、TRADE_FINISHED（交易结束，不可退款）
                    restmap.put("trade_status", alipayResponse.getTradeStatus());
                    restmap.put("total_amount",alipayResponse.getTotalAmount());
                    log.info("订单查询结果：" + alipayResponse.getTradeStatus());
                } else {
                    restmap.put("result",alipayResponse.getBody());
                    log.info("订单查询失败：" + alipayResponse.getMsg() + ":" + alipayResponse.getSubMsg());
                }
            }else {
                // 订单查询失败
                restmap = null;
            }
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        return restmap;
    }


    /**
     * 订单退款
     * @param orderno  商家交易订单号
     *
     */
    public static Map<String, Object> orderPayRefund(String orderno, String refund_amount,String refund_reason) {
        log.info("orderPayRefund");
        // 返回支付宝退款信息
        Map<String, Object> restmap = new HashMap<>();
        // 统一收单交易退款接口
        AlipayTradeRefundRequest alipayRequest = new AlipayTradeRefundRequest();
        // 只需要传入业务参数
        AlipayTradeRefundModel model = new AlipayTradeRefundModel();
        // 商户订单号与支付宝交易号选一即可
        model.setOutTradeNo(orderno);
        // 退款金额
        model.setRefundAmount(refund_amount);
        // 退款原因
        model.setRefundReason(refund_reason);
        //退款单号，如需部分退款，则此参数必传。
        model.setOutRequestNo(getRefundNo());
        alipayRequest.setBizModel(model);

        try {
            AlipayTradeRefundResponse alipayResponse = alipayClient.execute(alipayRequest);
            // 订单查询成功
            if (alipayResponse.isSuccess()) {
                // 调用成功，则处理业务逻辑
                if ("10000".equals(alipayResponse.getCode())) {
                    // 订单创建成功
                    restmap.put("out_trade_no", alipayResponse.getOutTradeNo());
                    restmap.put("trade_no", alipayResponse.getTradeNo());
                    // 用户的登录id
                    restmap.put("buyer_logon_id", alipayResponse.getBuyerLogonId());
                    //本次退款是否发生了资金变化 Y N
                    restmap.put("fund_change",alipayResponse.getFundChange());
                    //退款总金额
                    restmap.put("refund_fee",alipayResponse.getRefundFee());
                    // 退款支付时间
                    restmap.put("gmt_refund_pay", alipayResponse.getGmtRefundPay());
                    // 买家在支付宝的用户id
                    restmap.put("buyer_user_id", alipayResponse.getBuyerUserId());
                    log.info("订单退款结果：退款成功");
                } else {
                    log.info("订单查询失败：" + alipayResponse.getMsg() + ":" + alipayResponse.getSubMsg());
                    restmap.put("result",alipayResponse.getBody());
                }
            }else {
                // 订单查询失败
                restmap = null;
            }
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        return restmap;
    }

    /**
     * 退款查询
     * @param orderno
     *            商家订单号
     * @param out_request_no
     *            请求退款接口时，传入的退款请求号，如果在退款请求时未传入，则该值为创建交易时的外部交易号
     */
    public static Map<String, Object> orderPayRefundQuery( String orderno,String out_request_no) {
        log.info("orderPayRefundQuery");
        // 返回支付宝退款信息
        Map<String, Object> restmap = new HashMap<>();
        // 统一收单交易退款查询
        AlipayTradeFastpayRefundQueryRequest alipayRequest = new AlipayTradeFastpayRefundQueryRequest();
        // 只需要传入业务参数
        AlipayTradeFastpayRefundQueryModel model = new AlipayTradeFastpayRefundQueryModel();
        // 商户订单号
        model.setOutTradeNo(orderno);
        // 请求退款接口时，传入的退款请求号，如果在退款请求时未传入，则该值为创建交易时的外部交易号
        model.setOutRequestNo(out_request_no);
        alipayRequest.setBizModel(model);
        try {
            AlipayTradeFastpayRefundQueryResponse alipayResponse = alipayClient.execute(alipayRequest);
            if (alipayResponse.isSuccess()) {
                // 调用成功，则处理业务逻辑
                if ("10000".equals(alipayResponse.getCode())) {
                    // 订单创建成功
                    restmap.put("out_trade_no", alipayResponse.getOutTradeNo());
                    restmap.put("trade_no", alipayResponse.getTradeNo());
                    // 退款订单号
                    restmap.put("out_request_no", alipayResponse.getOutRequestNo());
                    // 退款原因
                    restmap.put("refund_reason", alipayResponse.getRefundReason());
                    // 订单交易金额
                    restmap.put("total_amount", alipayResponse.getTotalAmount());
                    // 订单退款金额
                    restmap.put("refund_amount", alipayResponse.getTotalAmount());
                    log.info("订单退款结果：退款成功");
                } else {
                    restmap.put("result",alipayResponse.getBody());
                    log.info("订单失败：" + alipayResponse.getMsg() + ":" + alipayResponse.getSubMsg());
                }
            }else{
                //订单查询失败
                restmap = null;
            }
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        return restmap;
    }

    /**
     * 退款单号
     *
     * @return
     */
    public static String getRefundNo() {
        // 自增8位数 00000001
        return "RNO" + new SimpleDateFormat("yyyyMMddHHmmssSSS").format(new Date()) + "00000001";
    }

    public static void main(String[] args) {
       orderPayRefund("20180809151611280","0.01","不喜欢");
      //  orderPayQuery("20180810133319380");
    }
}